#region Using Directives
using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Reflection;
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics;
using System.Globalization;
using System.Web;
#endregion Using Directives

namespace Minimal.Web
{
    public partial class QueryString
    {
        /// <summary>
        /// Represents metadata for a QueryString, used to allow query strings
        /// of unknown types to be automatically parsed in runtime.
        /// </summary>
        private class QueryStringMetadata
        {
            public QueryStringMetadata(Type queryStringType)
                : this(queryStringType, 1)
            { }

            private QueryStringMetadata(Type queryStringType, int version)
            {
                this._queryStringType = queryStringType;
                this._version = version;
            }

            #region QueryStringType
            [DebuggerBrowsableAttribute(DebuggerBrowsableState.Never)]
            private Type _queryStringType;

            /// <summary>
            /// The type that rendered the query string.
            /// </summary>
            public Type QueryStringType
            {
                [DebuggerStepThroughAttribute]
                get
                {
                    return this._queryStringType;
                }
            }
            #endregion QueryStringType

            #region Version
            [DebuggerBrowsableAttribute(DebuggerBrowsableState.Never)]
            private int _version;

            /// <summary>
            /// The version that generated the query string.
            /// </summary>
            public int Version
            {
                [DebuggerStepThroughAttribute]
                get
                {
                    return this._version;
                }
            }
            #endregion Version

            #region Parse
            public static QueryStringMetadata Parse(string metadata)
            {
                if (string.IsNullOrEmpty(metadata))
                {
                    return null;
                }

                string[] values = metadata.Split('&');
                QueryStringMetadata result = new QueryStringMetadata(
                    Type.GetType(HttpUtility.UrlDecode(values[1])),
                    Convert.ToInt32(HttpUtility.UrlDecode(values[0]), CultureInfo.InvariantCulture));
                return result;
            }
            #endregion Parse

            public override string ToString()
            {
                return HttpUtility.UrlEncode(this.Version.ToString(CultureInfo.InvariantCulture)) + '&' + HttpUtility.UrlEncode(this.QueryStringType.FullName);
            }
        }
    }
}
